﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection.Emit;

namespace Teal.Compiler {

    /// <summary>
    /// 表示一个编译器。用于存储相关的配置数据以及提供公共的编译辅助函数。
    /// </summary>
    public static partial class Compiler {
        #region 暂时不能删除

        public static BuiltinTypes BuiltinTypes = new BuiltinTypes();

        public static Report Report = new Report(new ConsoleReportPrinter());



        //public static void Parse(SourceFile file, ModuleDefinition module, ParserSession session, Report report) {
        //    Stream input;

        //    try {
        //        input = File.OpenRead(file.Name);
        //    } catch {
        //        report.Error(2001, "Source file `{0}' could not be found", file.Name);
        //        return;
        //    }

        //    // Check 'MZ' header
        //    if (input.ReadByte() == 77 && input.ReadByte() == 90) {

        //        report.Error(2015, "Source file `{0}' is a binary file and not a text file", file.Name);
        //        input.Close();
        //        return;
        //    }

        //    input.Position = 0;
        //    SeekableStreamReader reader = new SeekableStreamReader(input, Compiler.options.sourceEncoding, session.StreamReaderBuffer);

        //    Parse(reader, file, module, session, report);

        //    if (Compiler.options.debugOutputPath != null && Compiler.errorCount == 0 && !file.HasChecksum) {
        //        input.Position = 0;
        //        var checksum = session.GetChecksumAlgorithm();
        //        file.SetChecksum(checksum.ComputeHash(input));
        //    }

        //    reader.Dispose();
        //    input.Close();
        //}

        //public static void Parse(SeekableStreamReader reader, SourceFile sourceFile, ModuleDefinition module, ParserSession session, Report report) {
        //    var file = new CompilationSourceFile(module, sourceFile);
        //    module.AddTypeContainer(file);

        //    CSharpParser parser = new CSharpParser(reader, file, report, session);
        //    parser.parse();
        //}

        // Used for special handling of runtime dynamic context mostly
        // by error reporting but also by member accessibility checks
        public static bool IsRuntimeBinder;

        #endregion

        /// <summary>
        /// 获取当前编译后的包。
        /// </summary>
        public static PackageDefinition currentPackage = new PackageDefinition();

        /// <summary>
        /// 获取当前编译后的模块。
        /// </summary>
        public static ModuleDefinition currentModule {
            get {
                return currentPackage.mainModule;
            }
            set {
                currentPackage.mainModule = value;
            }
        }

        /// <summary>
        /// 开始编译操作。
        /// </summary>
        /// <returns>如果编译成功则返回 true，否则返回 false。</returns>
        public static void run() {

            // 检查配置。
            if (!checkOptions()) {
                return;
            }

            currentPackage.compile();
            return;




            var assembly = currentPackage;
            currentModule.SetDeclaringAssembly(assembly);

            // 导入系统库

            //var importer = new ReflectionImporter(currentModule, Compiler.BuiltinTypes);
            //assembly.Importer = importer;

            //var loader = new DynamicLoader(importer);
            //loader.LoadReferences(currentModule);

            if (!Compiler.BuiltinTypes.CheckDefinitions(currentModule))
                return ;

            // 定义容器。
            //currentModule.CreateContainer();

            //loader.LoadModules(assembly, currentModule.GlobalRootNamespace);

            currentModule.InitializePredefinedTypes();

            // 定义成员。

            //currentModule.DefineNamespace();

            //currentModule.resolveTypes();


            currentModule.Define();

            currentModule.HasTypesFullyDefined = true;

            if (Compiler.errorCount > 0)
                return ;

            // 解析程序集本身。
            assembly.Resolve();

            if (Compiler.errorCount > 0)
                return ;

            // 生成代码。
            assembly.Emit();

            if (Compiler.errorCount > 0) {
                return ;
            }

            currentModule.closeTypeBuilder();

            assembly.EmbedResources();

            if (Compiler.errorCount > 0)
                return ;

            assembly.save();

#if STATIC
			references_loader.Dispose ();
#endif

            return;
            return ;

        }

        /// <summary>
        /// 初始化编译器基本设置，导入相关模块。
        /// </summary>
        public static void reset() {
            currentPackage = new PackageDefinition();
        }

    }

}